import Taro from '@tarojs/taro';
import { Component, useState, useEffect } from 'react';
import { View } from '@tarojs/components';
import { Body } from '../../componets/public';
import { copyJson, isFun, stateMinute } from '../../common/tool';
import { CardItemType } from './type';
import { cardDirectionType } from '../../common/enum';
import { crateGroupArray } from './createCard';
import { getStaticState } from "../../state/static-store";
import { controlConfig, initHook, createLevel, initmaskControl } from './control';
import {
  markPoolCard,
  timeStemp,
  computedPoolPosition,
  markPoolCardPosition,
  poolSort,
  computedRemoveCard,
  revokeCard,
  isBeingEliminated,
  isGameFail
} from './computed'
import './sheep.scss';
const LEVEL_NUMBER = 5; // 最多5关;
/**
 * 卡片动画类型
 */
enum CARD_TRANSITION_TPYE  {
  /**
   * 移除
   */
  remvoe,
  /**
   * 过渡动画结束
   */
  transitionEnd
}
/**
 * 页面控制
 */
const controlPage = {
  maskTran: true,
  /**
   * 备份渲染数据
   */
  heapList: []
}

const showToast = (title = '已使用过该道具') => {
  Taro.showToast({
    title,
    icon: 'none',
    duration: 1000,
  })
}

/**
 * 卡片项
 */
const CardItem = function(props) {
  const cardClass = props.isZoom ? 'card-item-box view__narrow__sacle' : ' card-item-box ' ;
  const gameSyle = {
    left: `${props.left}rpx`,
    top: `${props.top}rpx`,
    zIndex: props.zIndex,
    width: `${props.width}rpx`,
    height: `${props.height}rpx`
  }
  const onClick = (() => {
    if (props.isGameBox && !props.isExistancePool) {
      isFun(props.onCardClick) && props.onCardClick({...props});
    }
  })
  const onTransitionEnd = (() => {
    if (props.isExistancePool) {
      isFun(props.onTransitionEnd) && props.onTransitionEnd(CARD_TRANSITION_TPYE.transitionEnd);
    };
  })
  const maskClass = `${cardClass} mask-card`;
  return (
    <>
      <View
        onTransitionEnd={() => onTransitionEnd()}
        hoverClass='card-item__haver'
        onClick={() => onClick()}
        className={cardClass}
        style={gameSyle}
        >
        {props.val}
      </View>
      {props.isMask ? <View className={maskClass} style={gameSyle}></View>: <View></View>}
    </>
  )
};
const GameEndPopup  = function ({reset, resurrection, levelNumber, isGameEnd, resurrectionControl, timeConsuming}) {
  const resucrrectionClass = resurrectionControl ? 'but resurrection but-used-tense' : 'but resurrection';
  const timeDifference: string = stateMinute(new Date().getTime() - timeConsuming)
  const IS_SMALL_SCREEN = getStaticState('isSizeScreen');
  return (<View className="popup">
    <View className={IS_SMALL_SCREEN ? 'result small-screen-result' : "result"}> {isGameEnd ? '已通关' :'未通关'}</View>
    <View className={IS_SMALL_SCREEN ? 'time-difference small-screen-diff': 'time-difference'}>
      <View>
        <View className='title'>用时</View>
        <View className='time'>{timeDifference}</View>
        <View className='level'>第{levelNumber}关</View>
      </View>
    </View>
    <View className={resucrrectionClass} hoverClass={resurrectionControl ? '' : 'but__hover'} onClick={() => resurrection()}>复活</View>
    <View className="but" hoverClass='but__hover' onClick={reset}>重新开始</View>
  </View>)
};
const TransitionAn = function({isTranMaskAnimation, onAnimationEnd}) {
  return (
    <View className={isTranMaskAnimation ? 'transition-an' : ''} onAnimationEnd={() => onAnimationEnd()}/>
  )
}
const ContentBody = function({timeConsuming, bodyClassName}) {
  const [levelNumber, setLevelNumber] = useState(0);
  const [cardHeapViweData, layerListData] = switchLevel(levelNumber);
  const [isEndGame, setIsEndGame] = useState(false);
  const [cardheapList, setCardHeapList] = useState(cardHeapViweData);
  const [cardPoolList, setCardPoolList] = useState< Array<CardItemType>>([]);
  const [layerList, setLayerList] = useState(layerListData);
  const [CardControl, setCardControl] = useState(controlConfig());
  const [hook, setHook] = useState(initHook());
  const [gameMaskControl, setGameMaskControl] = useState(initmaskControl());
  const [eliminate] = useState(3);
  const [isGameEnd, setIsGameEnd] = useState(false);
  useEffect(() => {
    if (controlPage.maskTran) {
      controlPage.maskTran = false;
      setTimeout(() => {
        const copyGameMaskControl = copyJson(gameMaskControl);
        copyGameMaskControl.isTranMaskAnimation = true;
        setGameMaskControl(copyGameMaskControl);
      }, 500);
    }
  })
  const reset = (() => {
    const pages = Taro.getCurrentPages();
    const currentPage = pages[pages.length - 1];
    controlPage.maskTran = true;
    currentPage.onLoad();
  })
  const endGame = (bool = true) => {
    setIsEndGame(bool);
  }
  const onCardClick = (currentCard: CardItemType) => {
    computedCardHeap(currentCard);
    saveHook();
  };
  const removeCardPoll = () => {
    const copyCardPoolList = copyJson(cardPoolList);
    const copyCardheapList = copyJson(cardheapList);

    const copyCardControl = copyJson(CardControl);
    if (copyCardControl.isRemove) {
      showToast();
      return;
    }
    if (copyCardPoolList.length === 0) {
      showToast('没有卡片可以移除哦');
      return;
    }
    if (!copyCardControl.isRemove) {
      Taro.showModal({
        title: '移除',
        content: "使用该道具移除3个卡片",
        success(res) {
          if (res.confirm) {
            saveHook();
            const [heapList, poolList] = computedRemoveCard({number: 3, heapList: copyCardheapList, poolList: copyCardPoolList});
            updateCardList(heapList, poolList);
            copyCardControl.isRemove = true;
            setCardControl(copyCardControl);
          }
        }
      })
    }
  };
  const shuflleTheCard = () => {
    if(CardControl.isShuflleTheCard) {
      showToast();
      return;
    }
    Taro.showModal({
      title: '洗牌',
      content: "使用该道具重新打乱卡片",
      success(res) {
        if (res.confirm) {
          const [newCardheapList,  newLayerList] = crateGroupArray(copyJson(cardheapList));
          const copyCardControl = copyJson(CardControl);
          copyCardControl.isShuflleTheCard = true;
          setCardControl(copyCardControl);
          setCardHeapList(newCardheapList);
          setLayerList(newLayerList);
        }
      }
    });
  };


  const whitdrawCard = () => {
    if(CardControl.isRevoke) {
      showToast();
      return;
    }
    Taro.showModal({
      title: '撤销',
      content: "撤销一次操作",
      success(res) {
        if (res.confirm) {
          const { odlPoolList, odlHeaplist, oblLayerList, copyHook }  = revokeCard(hook)
          const copyCardControl = copyJson(CardControl);
          copyCardControl.isRevoke = true;
          if (odlPoolList) {
            setCardPoolList(odlPoolList);
          }
          if (odlHeaplist) {
            setCardHeapList(odlHeaplist) ;
          };
          if (oblLayerList) {
            setLayerList(oblLayerList);
          }
          setHook(copyHook);
          setCardControl(copyCardControl);
        }
      }
    });
  };
  const resurrection = () => {
    if(CardControl.resucrrection) {
      showToast();
      return;
    }
    Taro.showModal({
      title: '复活',
      content: "当前局可复活一次",
      success(res) {
        if (res.confirm) {
          const copyCardControl = copyJson(CardControl);
          const { odlPoolList, odlHeaplist, oblLayerList, copyHook }  = revokeCard(hook)
          if (odlPoolList && odlHeaplist) {
            const [heapList, poolList] = computedRemoveCard({number: 5, heapList: odlHeaplist, poolList: odlPoolList});
            updateCardList(heapList, poolList);
          }
          if (oblLayerList) {
            setLayerList(oblLayerList);
          }
          copyCardControl.resucrrection = true;
          setHook(copyHook);
          setCardControl(copyCardControl);
          endGame(false);
        }
      }
    });
  };
  const onAnimationEndMask = () => {
    const copyGameMaskControl = copyJson(gameMaskControl);
    copyGameMaskControl.isTranMaskAnimation = false;
    setGameMaskControl(copyGameMaskControl);
    openNextShut();
  }
  function onTransitionEndCard(targetType) {
    if (Date.now() - timeStemp.cardUpdateTime < 499 ) {
      return ;
    };
    if (CardControl.isBeingEliminated) {
      return
    }
    CardControl.isBeingEliminated = isBeingEliminated(markPoolCard(copyJson(cardPoolList)), eliminate)
    // 卡片池分组缓存
    if (CardControl.isBeingEliminated) {
      setCardControl(CardControl)
      setTimeout(() => {
        CardControl.isBeingEliminated = false
        setCardControl(CardControl)
        // computedUpdateCardPool(targetType)
      }, 500)
    }
    computedUpdateCardPool(targetType)
  }
  /**
   * 计算更新卡池列表 / 动画结束之后调用
   */
  function computedUpdateCardPool (targetType) {
    const hasCount = markPoolCard(copyJson(cardPoolList))
    const { cachePoolCardList, destructionPool } = markPoolCardPosition(hasCount, eliminate)
    // 复制所有卡片数据
    const copyCardheapList = copyJson(cardheapList);
    const [sortCachPoolCardList,  hasRetainedPool, hasEnd] = poolSort(cachePoolCardList)
    const newCopyCardheapList = copyCardheapList.filter(item => !item.isDestruction)
    let cardListLen = newCopyCardheapList.length;
    newCopyCardheapList.map((card) => {
      if (destructionPool?.[card.position]?.isExistence) {
        card.isZoom = true;
      }
      if (card.isExistancePool) {
        cardListLen -=1;
      }
      if (CardControl.isBeingEliminated) {
        return card
      }
      return computedPoolPosition(card, hasRetainedPool);
    });
    if (CARD_TRANSITION_TPYE.transitionEnd === targetType) {
      if (isGameFail(sortCachPoolCardList, hasEnd)) {
        endGame(true);
      }
      if (cardListLen === 0) {
        newCopyCardheapList.map(card => {
          if (!card.isDestruction) {
            card.isZoom = true;
            card.isDestruction = true;
          }
        });
        setTimeout(() => {
          const copyGameMaskControl = copyJson(gameMaskControl);
          copyGameMaskControl.isTranMaskAnimation = true;
          setGameMaskControl(copyGameMaskControl);
        }, 500)
      }
      updateCardList(newCopyCardheapList, sortCachPoolCardList);
    }
  }
  /**
   * 更新卡片数据
   */
  function updateCardList(heap, pool){
    setCardHeapList(heap);
    setCardPoolList(pool);
  }
  function computedCardHeap (currentCard) {
    const { layer } = currentCard;
    const copyCardPoolList = copyJson(cardPoolList);
    copyCardPoolList.push(currentCard);
    const [sortPoolList, hasSort] = poolSort(copyCardPoolList);
    const newCardMap = copyJson(cardheapList);
    const copyLayerList = copyJson(layerList);
    if (
      Array.isArray(copyLayerList[layer - 1])
      && !currentCard.position?.match(cardDirectionType.left)
      && !currentCard.position?.match(cardDirectionType.right)
      ) {
      const idx = copyLayerList[layer - 1].indexOf(currentCard.position);
      if (idx !== -1) {
        copyLayerList[layer - 1].splice(idx, 1);
        if (copyLayerList[copyLayerList.length - 1].length === 0) {
          copyLayerList.pop();
        };
      };
    }
    setLayerList(copyLayerList);
    newCardMap.map(item => {
      const isRowLeft = item.position?.match(cardDirectionType.left);
      const isRowRight =  item.position?.match(cardDirectionType.right);
       if (copyLayerList.length === item.layer && !isRowRight && !isRowLeft) {
         item.isMask = false;
       }
      if (!item.isDestruction && (layer - item.layer) === 1 && isRowLeft && currentCard.position.match(cardDirectionType.left)) {
        item.isMask = false;
      };
      if (!item.isDestruction && (layer - item.layer) === 1 && isRowRight && currentCard.position.match(cardDirectionType.right)) {
        item.isMask = false;
      };
      const newCard = computedPoolPosition(item, hasSort);
      return newCard;
    });
    updateCardList(newCardMap, sortPoolList);
  };
  function openNextShut(){
    const level = levelNumber + 1;
    if (level > LEVEL_NUMBER) {
      endGame(true);
      setIsGameEnd(true);
      return;
    }
    const [nextCardList, nextlayerList] = switchLevel(level);
    updateCardList([...nextCardList,], []);
    setLayerList(nextlayerList);
    setLevelNumber(level);
  }
  function switchLevel (level: number) {
    return createLevel({level, publice: { eliminate: 3 }});
  }
  function saveHook() {
    const newHook = copyJson(hook);
    newHook.poolList.push(copyJson(cardPoolList));
    newHook.heapList.push(copyJson(cardheapList));
    newHook.layerList.push(copyJson(layerList));
    setHook(newHook);
  }
  const cardHeapView = createCardheapView(cardheapList, {onCardClick, onTransitionEnd: onTransitionEndCard});
  return (
    <Body className={bodyClassName} navText={'零了个零'}>
      <TransitionAn
        isTranMaskAnimation={gameMaskControl.isTranMaskAnimation}
        onAnimationEnd={() => onAnimationEndMask()}
        ></TransitionAn>
      <View className='game-box'>
        {cardHeapView}
      </View>
      <View className='bottom-pool'>
        <View className='card-pool' id='card-pool'>
        </View>
        <View className='but-box'>
          <View className={CardControl.isRemove ? 'prop-but prop-but-used' : 'prop-but'} onClick={() => removeCardPoll()}>
            移除
          </View>
          <View className={CardControl.isRevoke ? 'prop-but prop-but-used' : 'prop-but'} onClick={() => whitdrawCard()} >
            撤回
          </View>
          <View className={CardControl.isShuflleTheCard ? 'prop-but prop-but-used' : 'prop-but'} onClick={() => shuflleTheCard()}>
            洗牌
          </View>
        </View>
      </View>
      {isEndGame ? <GameEndPopup isGameEnd={isGameEnd} timeConsuming={timeConsuming} levelNumber={levelNumber} reset={reset} resurrection={resurrection} resurrectionControl={CardControl.resucrrection}></GameEndPopup> : <View></View>}
    </Body>
  )
}
function createCardheapView(list, props) {
  return list.map((item) => {
    const {
      url,
      val,
      isDestruction,
      type,
      left,
      top,
      isMask,
      layer,
      position,
      zIndex,
      width,
      height,
      index,
      isExistancePool,
      opacity,
      isZoom,
    } = item;
    return <CardItem
        url={url}
        val={val}
        left={left}
        top={top}
        index={index}
        zIndex={zIndex}
        isDestruction={isDestruction}
        position={position}
        type={type}
        isMask={isMask}
        layer={layer}
        width={width}
        height={height}
        isZoom={isZoom}
        isExistancePool={isExistancePool}
        opacity={opacity}
        isGameBox={true}
        onCardClick={props.onCardClick}
        onTransitionEnd={props.onTransitionEnd}
      ></CardItem>
  })
};
export default class Index extends Component {
  state: { isMaskPage: boolean};
  constructor(props){
    super(props);
    this.state = {
       isMaskPage: true,
    }
    setTimeout(() => {
      this.state.isMaskPage = false;
      this.setState(this.state)
      Taro.hideLoading();
    }, 2000);
    Taro.showLoading({
      title: '加载中...'
    });
  }
  onShareAppMessage (share) {
    if (share.from === 'button') {
      // 来自页面内转发按钮
      console.log(share.target)
    }
    return {
      title: '一起来看看',
      path: '/pages/sheep/sheep'
    }
  }
  componentDidMount () {}
  componentWillUnmount () {
    controlPage.maskTran = true;
  }
  componentDidShow () { }
  componentDidHide () { }
  render () {
    return (
      <View>
        {this.state.isMaskPage ? <View className='mask-page'></View> : <View></View>}
        <ContentBody bodyClassName='body-bg' timeConsuming={new Date().getTime()}></ContentBody>
      </View>
    )
  }
}
